/*
背景
航空公司的货运飞机往返于各个国家和货物分理中心之间，分理中心的货物运送到各个国家，再将各个国家发出的货物送到分理中心。

分理中心非常庞大，每个国家都有一个自己的货运站，每个货运站有两个平台用于堆放货物。其中 A 平台用于堆放运送到该国的货物，而 B 平台堆放着其它国家的货物。各个国家的货运站排成一个环形。

平时，有货运汽车沿着环形的线路在各个国家的货运站之间运行。货运汽车的仓库是非常狭窄的，先放进去的货物只能等后放进去的货物移走之后才能搬出来。

当货运汽车到达一个站点 X 时，它首先卸货。卸货的过程是：首先查看最外面的箱子是否标记着 X 标签，如果是，代表这是运送到 X 国的货物，则放到 A 平台上，如果不是，则把该货箱放到B平台货物队列的末尾，然后处理下一箱货。当 B 平台放满或者是车被搬空，则开始装货。装货的过程是：从 B 平台货物队列的开始处装车，把车装满或把 B 平台搬空则装货结束。车子开往下一个货运站。

卸下一箱货物和装载一箱货物均需要一分钟的时间，且假设当货车从一个货运站开往另一个货运站的时间为两分钟。

示意图


每天，货车和货运飞机都这样周而复始的运行着，直到有一天因为报酬的原因，分理中心的工人开始罢工。货运飞机依然运行，但却无法运走任何货物。

任务
你是老板的心腹，平时深受老板关照。因此，你决定停止罢工，独自担当起分理的任务。现在，分理中心已经堆积了大量的货物，你决定在开始前先写程序计算一下要完成搬运需要多长的时间。

输入
对于输入部分包含几组数据，第一行是一个整数SET，表明下面有几组数据，随后便是这几组输入数据。

对于每一组输入数据，其第一行为三个整数 N、S 和 Q。其中 N(2 <= N <= 100) 表示环中站的个数。S(1 <= S <= 100) 表示货车的最大容量，即货车同时可以装载多少箱货物。而 Q(1 <= Q <= 100) 表示 B 平台所能放置的货物的总数，假定该系统中所有货运站 B 平台的最大容量都相同。

从第二行往后一共有 N 行，每行一的第一个数字代表该站 B 平台上货物的总数，之后的每个数字代表每箱货物运送到哪个站。

输出
对于每组输入，你需要在独立的一行中输出完成该任务所需要的时间。
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#if defined(_WIN32) && !defined(__cplusplus)
#define inline __inline
#endif

#include <stdio.h>

#define STATION_MAX_NUM 100
#define MAX_LOAD_CAPACITY 100
#define B_ITEM_MAX_NUM 100

#define MAX_QUEUE_SIZE B_ITEM_MAX_NUM + 1

typedef unsigned char BYTE;
typedef BYTE ElemType;
typedef int BOOL; /* Boolean是布尔类型,其值是TRUE或FALSE */
#define TRUE 1
#define FALSE 0

typedef struct
{
	int base, top;
	int LoadCapacity;
	ElemType ItemDest[MAX_LOAD_CAPACITY];
}Car;

typedef struct
{
	int front, rear;
	int StationNo;
	int ItemCapacity;
	ElemType ItemDest[MAX_QUEUE_SIZE];
}Station;

typedef struct
{
	int StationNum;
	Station Stations[STATION_MAX_NUM];
}Circle;

void CarPush(Car *car, ElemType item)
{
	car->ItemDest[car->top] = item;
	++car->top;
}

ElemType CarPop(Car *car)
{
	--car->top;
	return car->ItemDest[car->top];
}

ElemType GetCarTop(const Car *car)
{
	return car->ItemDest[car->top - 1];
}

void StationEnQueue(Station *station, ElemType item)
{
	station->ItemDest[station->rear] = item;
	++station->rear;
	station->rear %= station->ItemCapacity;
}

ElemType StationDeQueue(Station *station)
{
	ElemType e = station->ItemDest[station->front];
	++station->front;
	station->front %= station->ItemCapacity;
	return e;
}

BOOL IsStationEmpty(const Station *station)
{ /* 若Q为空队列,则返回TRUE,否则返回FALSE */
	return station->front == station->rear;
}

BOOL IsStationFull(const Station *station)
{ /* 若Q为空队列,则返回TRUE,否则返回FALSE */
	return station->front == (station->rear + 1) % station->ItemCapacity;
}

BOOL IsCarEmpty(const Car *car)
{
	return car->top == car->base;
}

BOOL IsCarFull(const Car *car)
{
	return car->top - car->base == car->LoadCapacity;
}

int HandleGoods(Station *station, Car *car)
{
	int time = 0;
	while (!IsCarEmpty(car))
	{
		if (GetCarTop(car) == station->StationNo)
		{
			CarPop(car);
			++time;
		}
		else if (!IsStationFull(station))
		{
			BYTE item = CarPop(car);
			StationEnQueue(station, item);
			++time;
		}
		else break;
	}

	while (!IsStationEmpty(station) && !IsCarFull(car))
	{
		BYTE item = StationDeQueue(station);
		CarPush(car, item);
		++time;
	}
	return time;
}

BOOL IsTaskComplete(const Circle *circle, const Car *car)
{
	if(!IsCarEmpty(car))return FALSE;
	for (int j = 0; j < circle->StationNum; j++)
	{
		if (!IsStationEmpty(&circle->Stations[j])) return FALSE;
	}

	return TRUE;
}

int main()
{
	int n;
	scanf("%d", &n);

	for (int i = 0; i < n; i++)
	{
		Circle circle;
		Car car;
		car.top = 0;
		car.base = 0;

		int N, S, Q; // 环中站的个数----货车的最大容量---- B平台所能放置的货物的总数
		scanf("%d%d%d", &N, &S, &Q);
		circle.StationNum = N;
		car.LoadCapacity = S;

		for (int j = 0; j < circle.StationNum; j++)
		{
			circle.Stations[j].ItemCapacity = Q + 1;
			circle.Stations[j].StationNo = j + 1;
			circle.Stations[j].front = 0;
			circle.Stations[j].rear = 0;

			int itemNumB;
			scanf("%d", &itemNumB);
			for (int k = 0; k < itemNumB; k++)
			{
				BYTE itemDest;
				scanf("%hhd", &itemDest);
				StationEnQueue(&circle.Stations[j], itemDest);
			}
		}

		int allTime = 0;
		for (int j = 0; !IsTaskComplete(&circle, &car); j++)
		{
			int time = HandleGoods(&circle.Stations[j % circle.StationNum], &car);
			allTime += time;
			if (j != 0) allTime += 2;
		}
		printf("%d\n", allTime);
	}
}